package com.github.butid.data;

import com.alipay.remoting.ConnectionEventType;
import com.alipay.remoting.InvokeCallback;
import com.alipay.remoting.exception.RemotingException;
import com.alipay.remoting.rpc.RpcClient;
import com.github.butid.data.codec.RequestBody;
import com.github.butid.data.codec.ResultBody;
import com.github.butid.data.rpc.RpcCallback;
import com.github.butid.data.rpc.common.ButClientUserProcessor;
import com.github.butid.data.rpc.common.CONNECTEventProcessor;
import com.github.butid.data.rpc.common.DISCONNECTEventProcessor;
import org.springframework.stereotype.Component;

/**
 * Rpc请求客户端
 * @author wangjing.dc@qq.com
 * @since 2020/8/20
 */
@Component
public class RpcNettyClient {

    private RpcClient client;
    ButClientUserProcessor clientUserProcessor       = new ButClientUserProcessor();
    CONNECTEventProcessor clientConnectProcessor    = new CONNECTEventProcessor();
    DISCONNECTEventProcessor clientDisConnectProcessor = new DISCONNECTEventProcessor();

    public RpcNettyClient(){
        // 1. create a rpc client
        client = new RpcClient();
        // 2. add processor for connect and close event if you need
        client.addConnectionEventProcessor(ConnectionEventType.CONNECT, clientConnectProcessor);
        client.addConnectionEventProcessor(ConnectionEventType.CLOSE, clientDisConnectProcessor);

        client.registerUserProcessor(clientUserProcessor);
        // 3. do init
        client.init();
    }

    /**
     * 发送Rpc同步请求, 请求超时3秒
     * @param addr 请求地址（127.0.0.1:9000）
     * @param req 请求参数
     * @return
     * @throws RemotingException
     * @throws InterruptedException
     */
    public ResultBody sendSync(String addr, RequestBody req) throws RemotingException, InterruptedException {
        return this.sendSync(addr, req, 3000);
    }

    /**
     * 发送Rpc同步请求
     * @param addr
     * @param req
     * @param timeout
     * @return
     * @throws RemotingException
     * @throws InterruptedException
     */
    public ResultBody sendSync(String addr, RequestBody req, int timeout) throws RemotingException, InterruptedException {
        return (ResultBody) client.invokeSync(addr, req, timeout);
    }

    /**
     * 发送Rpc异步请求
     * @param addr
     * @param req
     * @param callback
     * @param timeout
     * @throws RemotingException
     * @throws InterruptedException
     */
    public void send(String addr, RequestBody req, RpcCallback callback, int timeout) throws RemotingException, InterruptedException {
        client.invokeWithCallback(addr, req, callback, timeout);
    }

    /**
     * 发送Rpc异步请求,请求超时3秒
     * @param addr
     * @param req
     * @param callback
     * @throws RemotingException
     * @throws InterruptedException
     */
    public void send(String addr, RequestBody req, RpcCallback callback) throws RemotingException, InterruptedException {
        this.send(addr, req, callback, 3000);
    }
}
